package com.imm.service.impl;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imm.common.Result;
import com.imm.dto.OrderDTO;
import com.imm.mapper.OrderMapper;
import com.imm.pojo.*;
import com.imm.service.*;
import com.imm.utils.BaseContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Resource
    private IUserService userService;

    @Resource
    private IAddressBookService addressBookService;

    @Resource
    private IShoppingCartService shoppingCartService;

    @Resource
    private IOrderDetailService orderDetailService;

    @Resource
    private OrderMapper orderMapper;

    @Override
    public Result<Page<OrderDTO>> pageOrder(int page, int pageSize, OrderDTO orderDTO) {
        Page<Order> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(orderDTO.getNumber() != null, Order::getNumber, orderDTO.getNumber())
                .between(orderDTO.getBeginTime() != null && orderDTO.getEndTime() != null,
                        Order::getOrderTime, orderDTO.getBeginTime(), orderDTO.getEndTime())
                .orderByDesc(Order::getCheckoutTime);
        page(pageInfo, wrapper);
        Page<OrderDTO> orderDTOPage = new Page<>();
        BeanUtils.copyProperties(pageInfo, orderDTOPage, "records");
        List<OrderDTO> lists = pageInfo.getRecords().stream().map( item -> {
            OrderDTO dto = new OrderDTO();
            BeanUtils.copyProperties(item, dto);
            AddressBook addressBook = addressBookService.getById(item.getAddressBookId());
            dto.setUserName(addressBook.getConsignee());
            return dto;
        }).toList();
        orderDTOPage.setRecords(lists);
        return Result.success(orderDTOPage);
    }

    @Override
    public Result<Page> userPage(int page, int pageSize) {
        // 获取用户Id
        Long userId = BaseContext.get();
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getUserId, userId);
        Page<Order> orderPage = new Page<>(page, pageSize);
        page(orderPage, wrapper);
        return Result.success(orderPage);
    }

    @Transactional
    @Override
    public Result<String> submit(Order order) {
        // 获取用户ID
        Long userId = BaseContext.get();
        // 生成订单号
        String orderNumber = UUID.randomUUID().toString(true);
        User user = userService.getById(userId);
        AddressBook addressBook = addressBookService.getById(order.getAddressBookId());
        // 统计金额
        LambdaQueryWrapper<ShoppingCart> shoppingCartLambdaQueryWrapper = new LambdaQueryWrapper<>();
        shoppingCartLambdaQueryWrapper.eq(ShoppingCart::getUserId, userId);
        List<ShoppingCart> shoppingCarts = shoppingCartService.list(shoppingCartLambdaQueryWrapper);
        double amount = 0;
        for (ShoppingCart s : shoppingCarts) {
            amount += s.getAmount() * s.getNumber();
        }
        order.setStatus(2);
        order.setAmount(amount);
        order.setNumber(orderNumber);
        order.setUserId(userId);
        order.setUserName(user.getName());
        order.setAddress(addressBook.getDetail());
        order.setOrderTime(LocalDateTime.now());
        order.setConsignee(addressBook.getConsignee());
        order.setPhone(addressBook.getPhone());
        order.setCheckoutTime(LocalDateTime.now());
        orderMapper.insert(order);
        // 将数据存入订单详细表
        List<OrderDetail> orderDetails = shoppingCarts.stream().map(item -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(order.getId());
            orderDetail.setAmount(item.getAmount());
            orderDetail.setNumber(item.getNumber());
            orderDetail.setImage(item.getImage());
            orderDetail.setDishId(item.getDishId());
            orderDetail.setDishFlavor(item.getDishFlavor());
            orderDetail.setName(item.getName());
            orderDetail.setSetmealId(item.getSetmealId());
            return orderDetail;
        }).collect(Collectors.toList());
        orderDetailService.saveBatch(orderDetails);
        // 清除购物车
        shoppingCartService.remove(shoppingCartLambdaQueryWrapper);
        return Result.success("订单创建成功");
    }

    @Override
    public Result<String> updateOrder(Order order) {
        updateById(order);
        return Result.success("修改成功");
    }

    /**
     * 再下一单
     * @param orderDTO 订单数据传输对象
     * @return 响应
     */
    @Transactional
    @Override
    public Result<String> again(OrderDTO orderDTO) {
        // 将订单信息拉取，并制作成购物车信息
        LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId, orderDTO.getId());
        // 获取订单详情
        List<OrderDetail> list = orderDetailService.list(orderDetailLambdaQueryWrapper);
        // 获取用户Id
        Long userId = BaseContext.get();
        // 进行处理
        List<ShoppingCart> shoppingCarts = list.stream().map(item -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            shoppingCart.setUserId(userId);
            shoppingCart.setAmount(item.getAmount());
            shoppingCart.setName(item.getName());
            shoppingCart.setNumber(item.getNumber());
            shoppingCart.setDishFlavor(item.getDishFlavor());
            shoppingCart.setImage(item.getImage());
            shoppingCart.setDishId(item.getDishId());
            shoppingCart.setSetmealId(item.getSetmealId());
            return shoppingCart;
        }).toList();
        log.info("进行插入{}", shoppingCarts);
        shoppingCartService.saveBatch(shoppingCarts);
        return Result.success("success!");
    }
}
